package com.khaled.protclass.model.prediction;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

import weka.classifiers.Classifier;
import weka.classifiers.meta.Stacking;
import weka.classifiers.trees.RandomForest;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;

public class Classification
{
	private Classifier classifier;

	public Classification(String modelPath) throws Exception
	{
		this.classifier = loadModel(modelPath);
	}

	private Classifier loadModel(String modelPath) throws Exception
	{
		ObjectInputStream modelStream = new ObjectInputStream(new FileInputStream(modelPath));

		Object modelObject = modelStream.readObject();

		modelStream.close();

		if (modelObject instanceof Stacking) { return (Stacking) modelObject; }
		if (modelObject instanceof RandomForest) { return (RandomForest) modelObject; }

		return null;
	}

	public double classify(StringBuffer stringFeatureVector) throws Exception
	{
		double[] featureVector = getVector(stringFeatureVector);

		Instances instances = getDataset(featureVector.length + 1);
		Instance newInst = new Instance(featureVector.length + 1);
		newInst.setDataset(instances);
		for (int i = 0; i < featureVector.length; i++)
		{
			newInst.setValue(i, featureVector[i]);
		}
		return classifier.classifyInstance(newInst);
	}

	private double[] getVector(StringBuffer stringFeatureVector)
	{
		String[] values = stringFeatureVector.toString().split(",");

		double[] featureVector = new double[values.length];

		for (int i = 0; i < featureVector.length; i++)
		{
			featureVector[i] = Double.parseDouble(values[i]);
		}

		return featureVector;
	}

	private Instances getDataset(int attributesNum)
	{
		FastVector attInfo = new FastVector(attributesNum);
		for (int i = 0; i < attributesNum; i++)
		{
			attInfo.addElement(new Attribute("a" + i));
		}
		Instances m_Instances = new Instances("VirulentCD", attInfo, 0);
		m_Instances.setClassIndex(attributesNum - 1);

		return m_Instances;
	}

}
